import 'dart:async';
import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:lib_bt/BleManager.dart';
import 'package:lib_bt/bean/BleBeanInterface.dart';
import 'package:lib_util/SPUtils.dart';

import '../../base/LedBleBeanInterface.dart';
import '../BleBean.dart';

class OtaUtil {
  ///开始OTA升级
  static void startOta(LedBleBeanInterface bleBean) {
    getFirmwareFile(bleBean).then((firmwareFileName) {
      if (firmwareFileName.isNotEmpty) {
        startOtaForFileName(bleBean, firmwareFileName);
      }
    });
  }

  static void startOtaForFileName(LedBleBeanInterface bleBean, String filePath) {
    loadFirmwareFile(filePath).then((value) {
      startOtaForFileData(bleBean, value);
    });
  }

  static void startOtaForFileData(LedBleBeanInterface bleBean, Uint8List data) {
    BleManager.instance.startOta(bleBean.address, data);
  }

  ///获取ota文件列表
  static Future<List<String>> getFirmwareFileList(String rootPath) async {
    String manifestContent = await rootBundle.loadString('AssetManifest.json');
    Map<String, dynamic> manifestMap = json.decode(manifestContent);
    List<String> imageNames = manifestMap.keys.where((String key) => key.contains(rootPath)).toList();
    return imageNames;
  }

  static Future<String> getFirmwareFile(LedBleBeanInterface bleBean) async {
    var rootPath = "";
    /*if (bleBean.isOldDevice) {
      rootPath = "assets/ota/old/";
    } else {
      rootPath = "assets/ota/new/";
    }*/
    rootPath = "assets/ota/new/";
    var fileList = await getFirmwareFileList(rootPath);
    String filePath = "";
    String tmpName = "";
    /*if (bleBean.isOldDevice) {
      tmpName = "_${ByteUtils.byte2Short([bleBean.bytes[14], bleBean.bytes[15]])}_";
    } else {
      tmpName =
          "_${bleBean.customerId.toString().padLeft(4, '0')}_${bleBean.height}x((${bleBean.width})|(XXX))_${bleBean.screenColorType.toString().padLeft(2, '0')}_";
    }*/
    tmpName =
    "_${bleBean.customerId.toString().padLeft(4, '0')}_${bleBean.height}x((${bleBean.width})|(XXX))_${bleBean.screenColorType.toString().padLeft(2, '0')}_";

    //print("文件名:$tmpName");
    RegExp regExp = RegExp(tmpName); // 匹配数字
    for (var item in fileList) {
      if (regExp.hasMatch(item)) {
        filePath = item;
        break;
      }
    }
    print(filePath);
    return filePath;
  }

  static Future<int> getFirmwareVersion(LedBleBeanInterface bleBean) async {
    var filePath = await getFirmwareFile(bleBean);
    if (filePath.isNotEmpty) {
      RegExp regExp = RegExp(r'(\d)+\.ufw'); // 匹配数字
      var firstMatch = regExp.firstMatch(filePath);
      if (firstMatch != null) {
        var group = firstMatch.group(0);
        if (group != null) {
          var split = group.split("\.");
          if (split.length == 2) {
            return int.parse(split[0]);
          }
        }
      }
    }
    return 0;
  }

  static Future<bool> hasOta(LedBleBeanInterface bleBean) async {
    int v = await getFirmwareVersion(bleBean);
    return v > bleBean.versionCode;
  }

  ///获取固件文件数据
  static Future<Uint8List> loadFirmwareFile(String fileName) async {
    ByteData data = await rootBundle.load(fileName);
    return data.buffer.asUint8List();
  }

  ///保存ota信息,防止重连丢失信息
  static void saveOtaInfo(BleBeanInterface bleBean) {
    print("保存信息:${bleBean.name}");
    print("保存信息:${bleBean.mac}");
    print("保存信息:${bleBean.bytes}");
    SPUtils.setAsString(bleBean.mac, jsonEncode(bleBean.bytes));
  }

  static List<int>? getOtaInfo(String mac) {
    //print("getOtaInfo:$mac");
    var asString = SPUtils.getAsString(mac);

    print("保存信息:${asString}");
    if (asString.isNotEmpty) {
      return jsonDecode(asString).cast<int>();
    }
    return null;
  }
}
